/*-------------------------------------------------------------------------
 - Copyright (c) 2024-2025 [XD-AMCC TEAM]
 - [XD-AMCC] is licensed under Mulan PSL v2.
 - You can use this software according to the terms and conditions of the Mulan PSL v2.
 - You may obtain a copy of Mulan PSL v2 at:
 -          http://license.coscl.org.cn/MulanPSL2
 - THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
 - OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 - TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 - See the Mulan PSL v2 for more details.
 ------------------------------------------------------------------------*/

/**
 * @brief Implement the type object pool.
 *
 * @author  WXQ#XDU
 * @date    2024.12
 */

#include <stdbool.h>

#include "../include/amcc_log.h"
#include "../include/amcc_hashmap.h"
#include "../include/typesys.h"


// -----------------------------------------------------------------------
//  PART 1 :  Implementation a type pool which stores all types
//


extern void type_destroy(t_type_ptr  pType);  // in typesys.c


static t_hashcode pool_hash_ (t_map_key K) {
    return amcc_hashcode((const char*)K);
}

static int pool_keyCmp_ (t_map_key K1, t_map_key K2) {
    const char * key1 = (const char*)K1;
    const char * key2 = (const char*)K2;
    return strcmp(key1, key2);
}

static void pool_freeEntry_ (t_map_key K, t_map_value V) {
    t_type_ptr value = (t_type_ptr)V;
    type_destroy(value);
}

// module level operation
t_hashmap_ptr  typepool_new () {

    t_hashmap_ptr mapPtr = hashmap_new(50, pool_hash_,
                                       pool_keyCmp_, pool_freeEntry_);
    log_trace("  Types Table has initialized");
    return mapPtr;
}


// module level operation
void  typepool_destroy (t_hashmap_ptr  mapPtr) {
    log_trace("  Types Table is destroying");

    hashmap_destroy(mapPtr );

    log_trace("  Types Table has destroyed");
}


t_type_ptr typepool_find (t_hashmap_ptr  mapPtr, const char* typeName) {
    return (t_type_ptr)hashmap_find(mapPtr, (t_map_key)typeName);
}


t_type_ptr typepool_put (t_hashmap_ptr  mapPtr, t_type_ptr typePtr) {
    t_mapresult_insert result = hashmap_put(mapPtr,
                                            (t_map_key)(typePtr->typeName),
                                            (t_map_value)typePtr);
    if (result.value == NULL && true == result.success) {
        return typePtr;
    } else if (result.value == NULL && false == result.success) {
        // fail on memory allocation
        return NULL;
    } else {
        return result.value;
    }
}



// -----------------------------------------------------------------------
//  PART 2 :  Implementation the expr-type-pool which stores
//            types of all expressions.
//


extern t_treemap_ptr typesys_get_exprTypePool();

// module level operation
t_treemap_ptr  expr_typepool_new () {
    t_treemap_ptr mapPtr = treemap_new(100, NULL);
    log_trace("  ExprType Table has initialized");
    return mapPtr;
}


// module level operation
void  expr_typepool_destroy (t_treemap_ptr mapPtr) {
    treemap_destroy(mapPtr);
    log_trace("  ExprType Table has destroyed");
}


t_type_ptr  expr_typepool_get (t_tree_ptr node) {
    t_treemap_ptr  mapPtr = typesys_get_exprTypePool();
    t_treemap_value V = treemap_get(mapPtr, (t_map_key)node);
    return (t_type_ptr)(V);
}


void  expr_typepool_put (t_tree_ptr node, t_type_ptr type) {
    t_treemap_ptr  mapPtr = typesys_get_exprTypePool();
    treemap_put( mapPtr, node, type );
}
